import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'EventDispatcher.dart';
import 'BodyWidget.dart';
import 'SharedData.dart';

BodyWidget bw=BodyWidget();

class BlueLE{

  FlutterBlue flutterBlue = FlutterBlue.instance;
  late BluetoothDevice? bleDevice;
  late BluetoothCharacteristic? readWriteChar;
  String serviceUUID="";
  String charUUID="";
  TextEditingController textController=TextEditingController();
  TextEditingController textController2=TextEditingController();
  late StreamSubscription<List<int>>? _notifyListenControl;

  void startScan() async{

    _notifyListenControl=null;
    bleDevice=null;

    flutterBlue.startScan(timeout: Duration(seconds: 5)).then((value) {
      List<Widget> items=[];
      for(ScanResult res in value){
        if(res.device.name.trim().isNotEmpty) {
          items.add(ListTile(
            title: Text("name:" + res.device.name),
            onTap: () {
              print("res.device.name:${res.device.name}");
              //EventDispatcher.dispatchEvent("onDialogDone",res.device);
              Get.back();
              Get.defaultDialog(
                title: res.device.name,
                content: Column(children: [
                  Row(children: [
                    Expanded(child: TextField(controller: textController,
                      decoration: const InputDecoration(
                        hintText: "service UUID",
                      ),
                    )),
                  ],),
                  Row(children: [
                    Expanded(child: TextField(
                          controller: textController2,
                          decoration: const InputDecoration(
                            hintText: "characteristic UUID",
                          ),
                        )),
                  ],),
                ],),
                textConfirm: "Connect",
                onConfirm: (){
                   serviceUUID=textController.text;
                   charUUID=textController2.text;
                   connectDevice(res.device);
                   Get.back();
                }
              );
              Timer(const Duration(seconds: 1),(){setBackData(res.device.name);});
            },
          ));
        }
      }
      print("startScan: value:"+value.toString());
      Get.defaultDialog(
        title: "BLE Devices",
        content: Column(children: items,),
      );
      flutterBlue.stopScan();
    });
  }

  void setBackData(String deviceName){
    String? storeInfo=SharedData.getData("BLE_$deviceName");
    if(storeInfo!=null){
      List arr=storeInfo.split("@");
      textController.text=arr[0];
      textController2.text=arr[1];
    }
  }

  void connectDevice(BluetoothDevice device){
    SharedData.setData("BLE_${device.name}","$serviceUUID@$charUUID");
    bleDevice=device;
    bleDevice?.connect().then((value){
      print("成功连接！");
      bw.showConnectState("${device.name} connected!",1);
      bleDevice?.discoverServices().then((List<BluetoothService> services) {
        bool found=false;
        for(BluetoothService service in services){
          print(service.uuid.toString());
          //匹配服务端service的uuid
          if (service.uuid.toString() == serviceUUID) {
            found=true;
            print("service found!");
            readWriteChars(service);
            break;
          }
        }
        if(!found){
          disconnect();
          bw.showConnectState("disconnect,service uuid can not match!",0);
        }
      }).onError((error, stackTrace) {
        bw.showConnectState("connect failed, error!",0);
      });
    });
  }

  void readWriteChars(BluetoothService service){
    bool found=false;
    List<BluetoothCharacteristic> characteristics = service.characteristics;
    for (BluetoothCharacteristic characteristic in characteristics) {
      var valuex = characteristic.uuid.toString();
      print("所有特征值 --- $valuex");
      //匹配服务端characteristic的uuid
      if(characteristic.uuid.toString() == charUUID) {
        print("匹配到正确的特征值");
        found=true;
        readWriteChar = characteristic;
        receiveData();
        break;
      }
    }
    if(!found){
      disconnect();
      bw.showConnectState("disconnect,characteristic uuid can not match!",0);
    }
  }

  void receiveData() async{
    await readWriteChar?.setNotifyValue(true);
    _notifyListenControl=readWriteChar?.value.listen((value) {
      if (value == null) {
        print("我是蓝牙返回数据 - 空！！");
        return;
      }
      print("我是蓝牙返回数据:${utf8.decode(value)}");
      bw.showCallbackInfo(utf8.decode(value));
    });

  }

  void sendData(String msg){
    if(bleDevice!=null && readWriteChar!=null) {
      readWriteChar?.write(utf8.encode(msg));
    }
  }

  void disconnect() async{
    if(bleDevice!=null){
      if(_notifyListenControl!=null){
        _notifyListenControl?.cancel();
        _notifyListenControl=null;
      }
      await bleDevice?.disconnect();
      bleDevice=null;
    }
    print("disconnetct!");
  }

}


class MyBLE extends StatelessWidget{

  @override
  Widget build(BuildContext context) {

    RxString theStr="jack".obs;
    RxInt theIndex=0.obs;

    BlueLE blue=BlueLE();

    EventDispatcher.addEventListener("showDialog_ble",(data){
      bw.showCallbackInfo("connecting....");
      blue.startScan();
    });
    EventDispatcher.addEventListener("disconnect_ble",(data){
      blue.disconnect();
    });
    EventDispatcher.addEventListener("sendData_ble",(data){
      blue.sendData(data);
    });

    return Scaffold(
      appBar: AppBar(title:const Text("BLE"),centerTitle: true,backgroundColor: Colors.purpleAccent, titleTextStyle: const TextStyle(color: Colors.white)),
      body: bw.getWidget(theStr,"ble"),
      bottomNavigationBar: Obx(()=> BottomNavigationBar(items: const [
        BottomNavigationBarItem(icon: Icon(Icons.keyboard_alt_outlined),label: "KEYBOARD"),
        BottomNavigationBarItem(icon: Icon(Icons.compare_arrows),label: "PAN"),
      ],
        onTap: (index){
          if(index==0){
            theStr.value="board";
          }else{
            theStr.value="pan";
          }
          theIndex.value=index;
        },
        currentIndex: theIndex.value,
      )),
    );
  }
}